--[[ 我自己制作的FBAS函数库,主要是宏,还有一些画线相关的函数 
      导入本模块后,需要用MyFBAS.runPerFrame(func)绑定每帧执行函数,这样才能使用宏相关的指令
      设定宏热键的方法是MyFBAS.setHotkey(n, macroTable),设定第n个lua热键为宏表
      
  直接从MyFBN改过来,未必能完全运行!
  
  By setycyas @2025-10-21

]]

MyFBAS = {
  -- 分辨率,根据游戏可能需要重载,不需要考虑旋转!这跟mame和fbn不同!
  X_RESOLUTION = 336, Y_RESOLUTION = 240,
  -- 宏指令表,在输入宏时记录,nil时表示无输入宏,有输入时用[帧数]记录joypad.set()的输入,
  -- 同时用['lastFrame']记录最后一帧的帧数
  _MACRO = nil,
  -- 暂停运行flag
  _pauseFlag = false,
  -- 已绑定过函数的flag
  _bindFlag = false,
}

-- 画线函数,指定x或y画一条直线
-- 私有函数,xy为"x"或"y",position指定位置
function MyFBAS._drawLine(xy, position, width, color)
  if width == nil then
    width = 1
  end
  if color == nil then
    color = 0xffffffFF
  end
  
  if width == 1 then
    if xy == "x" then
      gui.line(position, 0, position, MyFBAS.Y_RESOLUTION, color)
    else
      gui.line(0, position, MyFBAS.X_RESOLUTION, position, color)
    end
  else
    if xy == "x" then
      gui.box(position-math.floor(width/2), 0, 
        position+math.ceil(width/2), MyFBAS.Y_RESOLUTION, 
        color, color
      )
    else
      gui.box(0, position-math.floor(width/2), 
      MyFBAS.X_RESOLUTION, position+math.ceil(width/2), 
      color, color
    )
    end
  end
end
-- 画线用函数
function MyFBAS.xLine(x, width, color)
  MyFBAS._drawLine("x", x, width, color)
end
function MyFBAS.yLine(y, width, color)
  MyFBAS._drawLine("y", y, width, color)
end

-- 画中心方块函数,以x,y为中心,指定半宽半长和颜色
function MyFBAS.centerBox(x, y, halfW, halfH, color, colorBorder)
  if color == nil then
    color = 0xaa8800AA
  end
  if colorBorder == nil then
    color = 0xff0000FF
  end
  gui.box(x-halfW, y-halfH, x+halfW, y+halfH, color, colorBorder)
end

-- 输入宏指令,参数为宏指令数组,每一项如果有输入就是一个joypad.set需要的{},如果没有输入则为false
-- 无法执行返回false
function MyFBAS.inputMacro(macroTable)
  local currentFrame -- 当前帧
  local i, v
  -- 表已经存在,不再接受
  if MyFBAS._MACRO then
    return false
  end
  -- 设定新宏表,索引为帧数,把macroTable按当前帧增加的结果
  MyFBAS._MACRO = {}
  currentFrame = emu.framecount()
  --print("currentFrame", currentFrame)
  for i, v in ipairs(macroTable) do
    MyFBAS._MACRO[currentFrame+i] = v
  end
  MyFBAS._MACRO.lastFrame = currentFrame+(#macroTable)
  --print("Start running a macro:")
  --print(MyFBAS._MACRO)
  return true
end
-- 执行宏过程
function MyFBAS._doMacro()
  local currentFrame, macroTable
  local k, v
  --print("doMacro before MyFBAS._MACRO check!")
  -- 未设定不用处理
  if MyFBAS._MACRO == nil then
    return
  end
  -- 处理当前帧
  currentFrame = emu.framecount()
  --print("doMacro at " .. currentFrame)
  if MyFBAS._MACRO[currentFrame] then
    macroTable = joypad.get()
    for k, v in pairs(MyFBAS._MACRO[currentFrame]) do
      macroTable[k] = v
    end
    joypad.set(macroTable)
    --print("set macroTable at " .. currentFrame .. "frame:")
    --print(macroTable)
  end
  -- 帧数够表示宏完成
  if currentFrame >= MyFBAS._MACRO.lastFrame then
    MyFBAS._MACRO = nil
    --print("A Macro ends at " .. currentFrame .. "frame!")
  end
end
-- 设定lua热键n为某个宏,宏以宏表的形式记录
function MyFBAS.setHotkey(n, macroTable)
  local f
  f = function()
    --print("hotkey " .. n .." works!")
    MyFBAS.inputMacro(macroTable)
  end
  input.registerhotkey(n, f)
end

-- 把目标函数加入到每帧运行,运行时兼容宏,如果不能成功绑定返回nil,否则返回真实绑定的函数
function MyFBAS.runPerFrame(func)
  local f -- 绑定到每帧运行的函数 
  -- 已经绑定过
  if MyFBAS._bindFlag then
    return nil
  end
  -- 定义绑定的函数
  f = function()
    -- 暂停运行flag
    if MyFBAS._pauseFlag then
      return
    end
    -- 执行宏
    MyFBAS._doMacro()
    -- 执行设定的函数
    func()
  end
  -- 绑定
  emu.registerbefore(f)
  MyFBAS._bindFlag = true
  return f
end

--[[测试运行]]
if ... == nil then
  macroTable1 = {
    {["P1 Button 1"] = true}, {["P1 Button 1"] = true}, false, false, {["P1 Button 1"] = true},
    {["P1 Right"] = true}, {["P1 Right"] = true}, {["P1 Right"] = true},
  }
  testFun = function()
    MyFBAS.xLine(50)
    MyFBAS.yLine(50)
  end
  MyFBAS.setHotkey(1, macroTable1)
  MyFBAS.runPerFrame(testFun)
end

-- 导出
return MyFBAS